﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


// modified version of the Camera class in http://raytracer.codeplex.com/SourceControl/list/changesets

namespace SimpleRayTracer
{
    class Camera
    {
        public Vector3D upVector; // camera up vector
        public Vector3D target; // camera look at
        public Vector3D viewer; // eye position
        public double width; // scene width
        public double height; // scene height

        private double aspectRatio = 0.0;
        private double FOV = 0.0; // field of view
        private Vector3D direction;
        private Vector3D u; // u coord
        private Vector3D v; // v coord
        private Vector3D U; // u normalised
        private Vector3D V; // v normalised

        public Camera(Vector3D upVector, Vector3D viewer, Vector3D target, double width, double height)
        {
            if (height > 0)
            {
                this.aspectRatio = width / height;
            }
            else
            {
                this.aspectRatio = 0.0;
            }

            this.width = width;
            this.height = height;
            this.upVector = upVector;
            this.target = target;
            this.viewer = viewer;

            direction = target - viewer;
            direction = Vector3D.Normv(direction);

            u = Vector3D.Cross(direction, upVector);
            v = Vector3D.Cross(u, direction);

            U = Vector3D.Normv(u);
            V = Vector3D.Normv(v) / aspectRatio;
        }

        public double getFOV()
        {
            double halfWidth = width / 2;

            double camDistance = Vector3D.Modv(target - viewer);

            FOV = Math.Round(Math.Atan(halfWidth / camDistance), 2);

            return FOV;
        }

        public double getAspect()
        {
            return this.aspectRatio;
        }

        public Ray getRayFromCamera(double x, double y, double min, double max)
        {
            Ray ray = new Ray(new Vector3D(0, 0, 0), new Vector3D(0, 0, 0), min, max);

            //double tx = -1.0 + ((1.0 + 2.0 * x) / width);
            //double ty = -1.0 + ((1.0 + 2.0 * y) / height);
            double tx = (x / width) - 1;
            double ty = (y / height) - 1;

            ray.origin = viewer + ((U * tx) + (V * ty));
            ray.direction = direction;

            return ray;
        }
    }
}
